package com.fkdx.webman.result;

import com.fkdx.common.enums.sys.ErrCodeEnum;
import com.fkdx.common.enums.sys.SelectQueryResp;
import lombok.extern.log4j.Log4j2;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;
import java.net.URI;
import java.util.List;

/**
 * 全局Result处理类
 * 解决Controller、Service封装Result对象的冗余代码，统一处理响应结果为标准响应体
 *
 * @author liujia05
 */
@Log4j2
@ControllerAdvice
public class ResultHandler implements ResponseBodyAdvice<Object> {

  @Override
  public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
    return true;
  }

  @Override
  public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    List<String> header = request.getHeaders().get("x-requested-with");
    if (header == null || !header.get(0).equals("XMLHttpRequest")) {
      return body;
    }
    // 为了和就有逻辑兼容，只有白名单的uri才进行标准结果集包装
    if (!isWhiteList(request.getURI())) {
      return body;
    }

    // 这块是预防非标库的逻辑，手工在controller返回Result<T>，导致重复包装
    if (body instanceof Result || body instanceof SelectQueryResp) {
      return body;
    }

    Result<Object> result = new Result<>(ErrCodeEnum.SUCCESS.getErrCode(), ErrCodeEnum.SUCCESS.getErrMsg());

    Method method = returnType.getMethod();
    if (method != null && Void.TYPE.equals(method.getReturnType())) {
      result.setData(null);
      return result;
    }

    result.setData(body);
    return result;
  }

  private boolean isWhiteList(URI uri) {
    return true;
  }

}
